/* Define to prevent recursive inclusion */
#define _PLATFORM_C_

/* Files include */
#include "platform.h"

volatile uint8_t HasLoopedThroughMain = 0;

/***********************************************************************************************************************
  * @brief  Waiting for systick
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
bool is_timeout(void)
{
    if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) {
        SysTick->CTRL = 0;
        return 1;//TRUE
    }
    else {
        return 0;//FALSE
    }
}
/***********************************************************************************************************************
  * @brief  Systick configuration
  * @note   none
  * @param  n: delay time unit us
  * @retval none
  *********************************************************************************************************************/
static void set_timeout_usec(uint32_t n)
{
    uint32_t ticks = n * (48000000 / 1000000);

    SysTick->CTRL = 0;
    /* set reload value register */
    SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
    /* set current value register */
    SysTick->VAL = 0;
    /* enable SysTick timer and use internal clock source */
    SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_CLKSOURCE_Msk;
}
/***********************************************************************************************************************
  * @brief  Millisecond delay
  * @note   none
  * @param  n: delay time unit
  * @retval none
  *********************************************************************************************************************/
void Delay_us(uint32_t n)
{
    set_timeout_usec(n);
    while (!is_timeout());
}

/***********************************************************************************************************************
  * @brief  Millisecond delay
  * @note   none
  * @param  Millisecond: delay time unit
  * @retval none
  *********************************************************************************************************************/
void Delay_ms(uint32_t Millisecond)
{
  for(u32 i=0;i<Millisecond;i++)
	{
		Delay_us(1000);
	}
}



#if   defined (__ICCARM__)

#if   (__VER__ >= 9030001)

/* Files include */
#include <stddef.h>
#include <LowLevelIOInterface.h>

/***********************************************************************************************************************
  * @brief  redefine __write function
  * @note   for PR
  * @param  handle
  * @param  *buf
  * @param  bufSize
  * @retval nChars
  *********************************************************************************************************************/
size_t __write(int handle, const unsigned char *buf, size_t bufSize)
{
    size_t nChars = 0;

     /* Check for the command to flush all handles */
    if (-1 == handle)
    {
        return (0);
    }

     /* Check for stdout and stderr (only necessary if FILE descriptors are enabled.) */
    if ((_LLIO_STDOUT != handle) && (_LLIO_STDERR != handle))
    {
        return (-1);
    }

    for (/* Empty */; bufSize > 0; --bufSize)
    {
        USART_SendData(USART1, *buf);

        while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC))
        {
        }

        ++buf;
        ++nChars;
    }

    return (nChars);
}

#else

/***********************************************************************************************************************
  * @brief  redefine fputc function
  * @note   for PR
  * @param  ch
  * @param  f
  * @retval ch
  *********************************************************************************************************************/
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (uint8_t)ch);

    while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC))
    {
    }

    return (ch);
}

#endif

#elif defined (__GNUC__)

/***********************************************************************************************************************
  * @brief  redefine fputc function
  * @note   for PR
  * @param  ch
  * @param  f
  * @retval ch
  *********************************************************************************************************************/
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (uint8_t)ch);

    while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC))
    {
    }

    return (ch);
}

#else

/***********************************************************************************************************************
  * @brief  redefine fputc function
  * @note   for PR
  * @param  ch
  * @param  f
  * @retval ch
  *********************************************************************************************************************/
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (uint8_t)ch);

    while (RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC))
    {
    }

    return (ch);
}

#endif


uint8_t CRC8_MAXIM( uint8_t *dat,uint16_t len)
{
	uint8_t  crc_value=0xFF,j; //��ʼֵΪ0xff��Ҳ�кܶ��ʼֵΪ0x00�ģ��˴����޸�
	unsigned int    i;
	
	for(i=0;i<len;i++)
	{
		crc_value ^= *dat++;
		for(j=0;j<8;j++)
		{
			if(crc_value&0x80)
			{
				crc_value=(crc_value<<1)^0x31;//�����CRCУ���㷨�޸ĸö���ʽ��ֵ����
			}
			else
		  {
				crc_value=(crc_value<<1);
			}
		}
	}
	return crc_value;
}

void PLATFORM_KeyGPIOInit(void)
{
  GPIO_InitTypeDef gpioinitstruct;

  RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
	
  gpioinitstruct.GPIO_Pin 	= GPIO_Pin_12;
  gpioinitstruct.GPIO_Speed = GPIO_Speed_High;	
  gpioinitstruct.GPIO_Mode 	= GPIO_Mode_IPU;	
  GPIO_Init(GPIOA, &gpioinitstruct);	
}

/***********************************************************************************************************************
  * @brief  Initialize Platform
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void PLATFORM_Init(void)
{
#ifdef LOW_POWER_MODE
	PLATFORM_KeyGPIOInit();
	Delay_ms(5);
	if( GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12) == false )
	{
		Delay_ms(3500);
	}
	PLATFORM_AllGPIO_Configure();
#endif
	Uart1_McuInit(9600);	//Serial port initialization
	
}
/***********************************************************************************************************************
  * @brief  Initialize SysTick for delay function
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void PLATFORM_InitDelay(void)
{
    RCC_ClocksTypeDef RCC_Clocks;

    RCC_GetClocksFreq(&RCC_Clocks);

    if (SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000))
    {
        while (1)
        {
        }
    }

    NVIC_SetPriority(SysTick_IRQn, 0x0);
}

/***********************************************************************************************************************
  * @brief
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void PLATFORM_Reinit(void)
{
  SystemInit();
	PLATFORM_InitDelay();
	Uart1_McuInit(9600);
}

/***********************************************************************************************************************
  * @brief
  * @note   none
  * @param  none
  * @retval none
  *********************************************************************************************************************/
void PLATFORM_AllGPIO_Configure(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_0 | GPIO_Pin_2 | 
                                GPIO_Pin_4 | GPIO_Pin_5  | GPIO_Pin_7 |
                                GPIO_Pin_10 | GPIO_Pin_11 |
                                GPIO_Pin_12 | GPIO_Pin_15;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_All;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void EnterLowPowerStopMode(void)
{
	GPIOI2C_Bus_DeInit();
	
	Uart1_McuDeInit();
}

void TimerLowPowerHandler( void )
{
	if( CapSensorSampFlag == false )
	{  
		if( HasLoopedThroughMain < 5 )
		{
				HasLoopedThroughMain++;
		}
		else
		{
				HasLoopedThroughMain = 0;
				EnterLowPowerStopMode();
				/* DeepStop Mode */
				RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR, ENABLE);
				PWR_EnterSTOPMode(PWR_Mode_DeepStop, PWR_StopEntry_WFI);
				
				PLATFORM_Reinit();
		}
	}
}

//选择排序空间复杂度为O(1),时间复杂度为O(n^2)
void sort(float *a, int l) {
    int i, j, max_idx;
    for (i = 0; i < l - 1; i++) {
        max_idx = i;
        for (j = i + 1; j < l; j++) {
            if (a[j] > a[max_idx]) { // 找最大值下标
                max_idx = j;
            }
        }
        // 交换 a[i] 和 a[max_idx]
        float temp = a[i];
        a[i] = a[max_idx];
        a[max_idx] = temp;
    }
}


